package sdk.pay;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.net.http.SslError;
import android.os.Build;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.webkit.SslErrorHandler;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.net.URLDecoder;

import sdk.pay.basepay.UnifiedPay;
import sdk.pay.listener.PayUtilCallBack;
import sdk.pay.model.PayInfo;
import sdk.pay.model.UnifiedPayHelper;
import sdk.pay.model.WapPay;
import sdk.pay.utils.PayLogUtil;
import sdk.pay.utils.PayTimeUtil;

public final class PayWebView extends WebView implements PayWebViewInterface {
    private PayInfo mPayInfo;
    private static final String SCHEME = "scheme=";
    private MyWebViewClient mMyWebViewClient;
    private SimpleWebViewClient mSimpleWebViewClient;
    private WapPay mWapPay;
    private UnifiedPay.CallBack mCallBack;
    private PayTimeUtil mPayTimeUtil;

    public PayWebView(Activity activity, PayInfo payInfo) {
        super(activity);
        mPayInfo = payInfo;
        initSettings();
        initCallBack();
        mPayTimeUtil = new PayTimeUtil(activity);
    }

    public PayWebView(Activity activity, PayUtilCallBack payUtilCallBack, PayInfo payInfo) {
        super(activity);
        mPayInfo = payInfo;
        initSettings();
        initCallBack();
        mPayTimeUtil = new PayTimeUtil(activity, payUtilCallBack);
    }

    @Override
    public void clear() {
        stopLoading();
        clearHistory();
        removeAllViews();
        destroy();
    }

    private void initCallBack() {
        mCallBack = new UnifiedPay.CallBack() {
            @Override
            public void prepareLeave() {
                getSettings().setJavaScriptEnabled(false);
                clearCache(true);
            }
        };
    }

    @SuppressLint("JavascriptInterface")
    private void initSettings() {
        WebSettings settings = getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setAllowFileAccess(false);
        settings.setSupportZoom(false);
        settings.setBlockNetworkImage(true);
        settings.setAppCacheEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setCacheMode(WebSettings.LOAD_DEFAULT);
        if (Build.VERSION.SDK_INT >= 19) {
            settings.setLoadsImagesAutomatically(true);
        } else {
            settings.setLoadsImagesAutomatically(false);
        }
        settings.setDomStorageEnabled(true);
        settings.setBlockNetworkLoads(false);
        mMyWebViewClient = new MyWebViewClient();
        mSimpleWebViewClient = new SimpleWebViewClient();
    }

    @Override
    public void loadUrl(String url, boolean isPilotRun) {
        getSettings().setJavaScriptEnabled(true);
        mPayTimeUtil.setTimeData(null);
        boolean ret = isPayUrl(url);
        if (null == mWapPay) {
            mWapPay = new WapPay(url, isPilotRun, getContext());
        } else {
            mWapPay.setContent(url);
            mWapPay.setIsPilotRun(isPilotRun);
        }
        if (ret) {
            mPayTimeUtil.setTimeData("ret_normal");
            setWebViewClient(mSimpleWebViewClient);
            UnifiedPayHelper.pay(mCallBack, mWapPay);
        } else {
            setWebViewClient(mMyWebViewClient);
            loadUrl(url);
        }
    }

    private boolean isPayUrl(String url) {
        return url.startsWith("alipays://") || url.contains("alipayqr") || url.startsWith("intent://")
                || url.startsWith("weixin://") || url.startsWith("mqqapi://");
    }


    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.getSettings().setBlockNetworkImage(false);
            if (!view.getSettings().getLoadsImagesAutomatically()) {
                PayLogUtil.logFifth("setLoadsImagesAutomatically");
                view.getSettings().setLoadsImagesAutomatically(true);
            }
            boolean ret = isPayUrl(url);
            if (ret) {
                mPayTimeUtil.setTimeData("shouldOverrideUrlLoading ret_normal");
                mWapPay.setContent(url);
                UnifiedPayHelper.pay(mCallBack, mWapPay);
                return true;
            }
            PayLogUtil.logBase("shouldOverrideUrlLoading url = " + url);
            if (url.contains(SCHEME)) {
                mPayTimeUtil.setTimeData("shouldOverrideUrlLoading scheme_normal");
                int index = url.indexOf(SCHEME);
                index += SCHEME.length();
                String shortUrl = url.substring(index);
                shortUrl = URLDecoder.decode(shortUrl);
                PayLogUtil.logFifth("shortUrl = " + shortUrl);
                mWapPay.setContent(shortUrl);
                UnifiedPayHelper.pay(mCallBack, mWapPay);
                return true;
            }
            if (null != mPayInfo) {
                // to avoid to launch this,if the condition is not right
                String aliUrl = mPayInfo.getAliUrl();
                String aliImgId = mPayInfo.getAliImgId();
                if (!TextUtils.isEmpty(aliImgId) && !TextUtils.isEmpty(aliUrl)) {
                    PayLogUtil.logBase(String.format("aliUrl %s, aliImgId %s", aliUrl, aliImgId));
                    loadUrl("javascript:window.location.href=document.getElementById('" + mPayInfo.getAliImgId() + "').value");
                }
            }
            return false;
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            PayLogUtil.logBase("onReceivedSslError SslError = " + error.getUrl());
            handler.proceed();
        }
    }

    private class SimpleWebViewClient extends WebViewClient {
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            PayLogUtil.logBase("onReceivedSslError SslError = " + error.getUrl());
            handler.proceed();
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            mPayTimeUtil.setTimerControl(-2);//pay cancel
        }
        return super.onKeyDown(keyCode, event);
    }
}

